package io.gitee.thant.entity;

import java.util.HashMap;
import java.util.Map;

import io.gitee.thant.utils.LogHelper;

public class Result implements Cloneable {
	private static final int okCol = 0;   //成功
	private static final int msgCol = 1;  //错误信息
	private static final int datCol = 2;  //数据
	private static final int debugCol = 3;//debug
	private String[] colDef = null;

	private static final int okVal = 0;   //成功值
	private static final int errVal = 1;  //错误值
	private Object[] okDef = null;
	
	private Map<String, Object> data = new HashMap<String, Object>();

	public Result() {
		init(null, null);
	}
	
	public Result(String colfmt, Object[] okJudge) {
		init(colfmt, okJudge);
	}
	
	private void init(String colfmt, Object[] okJudge) {
		colDef = new String[]{"ok", "message", "data", "debug"};
		okDef = new Object[]{true, false};

		if (null !=colfmt && null != okJudge) {
			String[] tmpColDef = colfmt.split(",");
			if (tmpColDef.length>=4 && okJudge.length>=2) {
				colDef = tmpColDef;
				okDef = okJudge;
			}
		}

		getData(); //init datCol
		setOK();
	}

	public String getMessage() {
		return (String)data.get(colDef[msgCol]);
	}
	public void setMessage(String message) {
		data.put(colDef[msgCol], message);
	}
	
	public void put(String key, Object val) {
		Map<String, Object> userdata = getData();
		userdata.put(key, val);
	}
	
	public Object get(String key) {
		Map<String, Object> userdata = getData();
		return userdata.get(key);
	}
	
	private String getStackInfo(StackTraceElement[] stackTraceElements) {
		StringBuilder sb = new StringBuilder(stackTraceElements[2].getClassName());
		sb.append('.').append(stackTraceElements[2].getMethodName())
			.append(":").append(stackTraceElements[2].getLineNumber());
		return sb.toString();
	}
	
	public void setError(String msg) {
		data.put(colDef[okCol], okDef[errVal]);
		data.put(colDef[msgCol], msg);
		data.put(colDef[debugCol], getStackInfo(Thread.currentThread().getStackTrace()));
	}
	public void setErrorLog(String msg) {
		setError(msg);
		LogHelper.error(msg);
	}
	public void setError(Exception e) {
		data.put(colDef[okCol], okDef[errVal]);
		data.put(colDef[msgCol], e.toString());
		data.put(colDef[debugCol], getStackInfo(e.getStackTrace()));
	}
	public void setErrorLog(Exception e) {
		setError(e);
		LogHelper.error(e);
	}
	public void setOK(String msg) {
		data.put(colDef[okCol], okDef[okVal]);
		data.put(colDef[msgCol], msg);
		data.put(colDef[debugCol], null);
	}
	public void setOK() {
		setOK("");
	}
	public void setResult(boolean result) {
		data.put(colDef[okCol], okDef[result ? okVal : errVal]);
	}
	
	public void setData(Map<String, Object> map) {
		Map<String, Object> userdata = getData();
		if (null == map) {
			userdata.clear();
		} else {
			data.put(colDef[datCol], map);
		}
	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> getData() {
		Object rawdata = data.get(colDef[datCol]);
		if (null == rawdata) {
			rawdata = new HashMap<String, Object>();
			data.put(colDef[datCol], rawdata);
		}
		return (Map<String, Object>)rawdata;
	}

	public boolean isOk() {
		return judge(data.get(colDef[okCol]));
	}
	
	public String getDebug() {
		return (String)data.get(colDef[debugCol]);
	}
	
	private boolean judge(Object val) {
		return okDef[okVal].equals(val);
	}
	
	public Map<String, Object> Transfiguration() {
		return data;
	}
	
	public void copy(Result sour) {
		data.clear();
		data.putAll(sour.data);
		colDef = sour.colDef.clone();
		okDef = sour.okDef.clone();
	}
	
	@Override
	protected Object clone() {
		Result newone = new Result();
		newone.copy(this);
		return newone;
	}
}
